#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QMouseEvent>
#include <math.h>
#include <QMessageBox>
#include <QTimer>
#include <QDebug>
#include <QApplication>
#include <QWidget>
#include <QPushButton>



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager();

    QObject::connect(manager, &QNetworkAccessManager::finished,
             this, [=](QNetworkReply *reply)//λ函数表达式
              {
                 if (reply->error())//
                 {
                     qDebug() << reply->errorString();
                     return;
                 }

                 QString answer = reply->readAll();
                 QJsonDocument jsonResponse = QJsonDocument::fromJson(answer.toUtf8());
                 QJsonObject jsonObject = jsonResponse.object();

                 auto mode = jsonObject["mode"].toInt();
                 if(mode == 1)
                 {
                     userID = jsonObject["userID"].toString();
                 }
                 else if(mode == 2)
                 {
                     //返回值2，说明获取数据列表
                     QJsonArray jsonArray = jsonObject["operationList"].toArray();

                     operationModel tmp;
                     foreach (const QJsonValue & value, jsonArray)
                     {
                         QJsonObject obj = value.toObject();
                         tmp.x = obj["x"].toString().toInt();
                         tmp.y = obj["y"].toString().toInt();
                         tmp.color = obj["color"].toString().toInt();
                         tem.userId= obj["userID"].toString().toInt();
                     }

                    qDebug()<< tmp.x<<"  "<<tmp.y<<"  "<<tmp.color <<"  " << myColor;

                    if(isUploading)
                    {
                        Uploaded = (tmp.color == myColor);
                        if(Uploaded)
                            isUploading = false;
                    }

                     if(tmp.color != 0)
                     {

                         if(myColor == 0)
                             myColor = -1;

                         if(operation.color != tmp.color)
                         {
                             clickPosRow =  tmp.x;
                             clickPosCol =  tmp.y;
                             game->actionBynet(clickPosRow,clickPosCol);
                             update();
                             operation.x = tmp.x;
                             operation.y = tmp.y;
                             operation.color = tmp.color;
                         }

                     }else{
                       if(Uploaded)
                       {
                           myColor = 0;
                           operation.color=0;
                           game->startGame(game_type);
                           game->gameStatus = PLAYING;
                       }
                     }

                     //最后一个数据肯定是最新的
                 }
                 else if(mode == 3)
                 {
                     //返回值3，提交坐标成功
                   return;  // QMessageBox::information(this,"alert","提交坐标成功");
                 }

             }
         );




    this->setFixedSize(
     MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE,
     MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE);
}

MainWindow::~MainWindow()
{
    delete ui;//删除界面
}

void MainWindow::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing); //设置抗锯齿

    for(int i=0;i<BOARD_GRAD_SIZE+1;i++)
    {

        painter.drawLine(MARGIN+BLOCK_SIZE*i,MARGIN,
                         MARGIN+BLOCK_SIZE*i,this->height()-MARGIN);
        //从上到下，第(i+1)横线
        painter.drawLine(MARGIN,MARGIN+BLOCK_SIZE*i,
                         this->width()-MARGIN,MARGIN+BLOCK_SIZE*i);//绘图
    }

    QBrush brush;//绘制鼠标目前的点位
    brush.setStyle(Qt::SolidPattern);
    //防止鼠标出界
    if(clickPosRow>0 && clickPosRow<BOARD_GRAD_SIZE &&
       clickPosCol>0 && clickPosCol<BOARD_GRAD_SIZE &&
        game->gameMapVec[clickPosRow][clickPosCol]==0)
    {

        if(game->playerFlag){
            brush.setColor(Qt::black);
        }
        else
        {
            brush.setColor(Qt::white);
        }
        painter.setBrush(brush);
        painter.drawRect(MARGIN+BLOCK_SIZE*clickPosCol-MARK_SIZE/2,MARGIN+BLOCK_SIZE*clickPosRow-MARK_SIZE/2,MARK_SIZE,MARK_SIZE);
    }
    for(int i=0;i<BOARD_GRAD_SIZE;i++){
        for(int j=0;j<BOARD_GRAD_SIZE;j++){
            if(game->gameMapVec[i][j]==1){
                brush.setColor(Qt::black);
                painter.setBrush(brush);
                painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_RADIUS,MARGIN+BLOCK_SIZE*i-CHESS_RADIUS,CHESS_RADIUS*2,CHESS_RADIUS*2);
            }
            else if(game->gameMapVec[i][j]==-1)
            {
                brush.setColor(Qt::white);
                painter.setBrush(brush);
                painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_RADIUS,MARGIN+BLOCK_SIZE*i-CHESS_RADIUS,CHESS_RADIUS*2,CHESS_RADIUS*2);
            }

        }
    }
    //判断输赢
    if(clickPosCol>0 && clickPosCol<BOARD_GRAD_SIZE &&
       clickPosRow>0 && clickPosRow<BOARD_GRAD_SIZE &&
       (game->gameMapVec[clickPosRow][clickPosCol]==1||game->gameMapVec[clickPosRow][clickPosCol]==-1))
    {  //代碼解析：game->gameMapVec[clickPosRow][clickPosCol]==1||game->gameMapVec[clickPosRow][clickPosCol]==-1，防止因為5個0(空白)相連也被判勝利
        if(game->isWin(clickPosRow,clickPosCol) && game->gameStatus == PLAYING){
            game->gameStatus = WIN;
            QString str;
            str = game->gameMapVec[clickPosRow][clickPosCol]==1?"黑棋":"白棋";
            QMessageBox::StandardButton btnValue = QMessageBox::information(this,"五子棋嬴家",str+"获得胜利");
            if(btnValue == QMessageBox::Ok){
                game->startGame(game_type);
                game->gameStatus = PLAYING;
            }
            QString url = "http://flask.graylightseeker.cloud/clear";
            request.setUrl(QUrl(url));
            manager->get(request);
            myColor = 0;
            operation.color=0;
        }
    }
}
//初始化




void MainWindow::initGame()
{
    game = new GameModel();

    game_type = temtype;
    game->gameStatus = PLAYING;
    game->startGame(game_type);

// ////////////////////////////////////////////////////////////

    if(game_type == net)
    {
        QString url = "http://flask.graylightseeker.cloud/getUserID";
        request.setUrl(QUrl(url));
        manager->get(request);

        url = "http://flask.graylightseeker.cloud/clear";
        request.setUrl(QUrl(url));
        manager->get(request);


        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(updateData()));
        timer->start(1000); //每一秒抓取一次数据

    }


    update();

   // widget.show();
}

void MainWindow::mouseMoveEvent(QMouseEvent* event)
{
    //确定鼠标位置
    int x = event->x();
    int y = event->y();

    //棋盘边缘不能落子，方法同上次的实现方法
    if(x>=MARGIN+BLOCK_SIZE/2&&
           x<this->width()-MARGIN-BLOCK_SIZE/2&&
           y>=MARGIN+BLOCK_SIZE/2&&
           y<this->height()-MARGIN-BLOCK_SIZE/2){

        int col = (x-MARGIN)/BLOCK_SIZE;
        int row = (y-MARGIN)/BLOCK_SIZE;

        int leftTopPosX = MARGIN+BLOCK_SIZE*col;
        int leftTopPosY = MARGIN+BLOCK_SIZE*row;


        clickPosRow = -1; //最终值初始化
        clickPosCol = -1;
        int len = 0;
        selectPos = false;


        len = sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY)*(y-leftTopPosY));
        if(len<POS_OFFSET)
        {
            clickPosRow = row;
            clickPosCol = col;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                selectPos = true;
            }
        }

        len = sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY)*(y-leftTopPosY));
        if(len<POS_OFFSET){
            clickPosRow = row;
            clickPosCol = col+1;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                selectPos = true;
            }
        }

        len = sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));
        if(len<POS_OFFSET){
            clickPosRow = row+1;
            clickPosCol = col;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                selectPos = true;
            }
        }

        len = sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));
        if(len<POS_OFFSET)
        {
            clickPosRow = row+1;
            clickPosCol = col+1;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                selectPos = true;
            }
        }
    }

    update();//重新绘制棋盘
}

void MainWindow::mouseReleaseEvent(QMouseEvent* event)
{
    if(selectPos == false)
    {
        return;
    }
    else
    {
        selectPos = false;
    }
    //由人來下棋
   if(game_type== MAN)
   {
        chessOneByPerson();
   }
    else if(game_type == AI)
    {
        chessOneByPerson();
        QTimer::singleShot(AI_THINK_TIME,this,SLOT(chessOneByAI()));//ai的思考时间
    }
    else if(game_type == net)
    {
        chessOneBynet();
    }



   // ////// //////////////////////////////////////////////////////////////////////////

}

void MainWindow::chessOneByPerson()
{
    if(clickPosRow!=-1 && clickPosCol!=-1 && game->gameMapVec[clickPosRow][clickPosCol]==0)
    {
        //落子
        game->actionByPerson(clickPosRow,clickPosCol);

        update();
    }
}
void MainWindow::chessOneBynet ()
{
    if(clickPosRow!=-1 && clickPosCol!=-1 && game->gameMapVec[clickPosRow][clickPosCol]==0)
    {

        //我的颜色和上次颜色相同且 我的颜色不为0，说明上一步棋是我下的， 就直接返回
         if(operation.color != 0 && operation.color == myColor)
         {
             return;
         }

         //初始化情况
        //如果我的颜色是0，并且操作记录是空的，那么操作合法，并且把我的颜色设置成黑色
         //this is the initial situation

        if(myColor == 0)
        {
            if(operation.color == 0)
                myColor = 1;
        }

        game->actionBynet(clickPosRow,clickPosCol);
        update();
        QString url = "http://flask.graylightseeker.cloud/submit?x=%1&y=%2&color=%3";
        url = url.arg(clickPosRow).arg( clickPosCol).arg(myColor);
        request.setUrl(QUrl(url));
        manager->get(request);
        isUploading = true;
        Uploaded = false;

        operation.color = myColor;
        operation.x = clickPosRow;
        operation.y = clickPosCol;

    }

}

void MainWindow::chessOneByAI()
{

    game->actionByAI(clickPosRow,clickPosCol);
    update();
}

void MainWindow::updateData()
{
    QString url = "http://flask.graylightseeker.cloud/getOperationLists";
    request.setUrl(QUrl(url));
    manager->get(request);
}

